package com.wash.shoes.controller.pc;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.GetBucketPolicyResult;
import com.aliyun.sts20150401.Client;
import com.aliyun.sts20150401.models.AssumeRoleRequest;
import com.aliyun.sts20150401.models.AssumeRoleResponse;
import com.aliyun.sts20150401.models.AssumeRoleResponseBody;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.models.RuntimeOptions;
import com.ruoyi.common.core.domain.R;
import com.wash.shoes.oss.ConstantProperties;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

@Log4j2
@Api(tags = {"PC-阿里云OSS"})
@RestController
@RequestMapping({"/aliyun", "/dev-api/aliyun"})
public class StsAliyunController {

    @Autowired
    private Client stsClient;

    @Autowired
    RedissonClient redissonClient;

    @ApiOperation("获取签名Test")
    @GetMapping("/getTokenForOssUploadTest")
    public R<HashMap<String, String>> generateStsTokenTest() {

        String endpoint = "http://oss-cn-heyuan.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        DefaultCredentialProvider credentialsProvider = new DefaultCredentialProvider(ConstantProperties.KEYID, ConstantProperties.KEYSECRET);
        // 填写Bucket名称，例如examplebucket。
        String bucketName = "shoeswasher";
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
        GetBucketPolicyResult result = ossClient.getBucketPolicy(bucketName);

        return null;
    }


    @ApiOperation("获取签名")
    @GetMapping("/getTokenForOssUpload")
    public R<HashMap<String, String>> generateStsToken() {

        RBucket<String> signCache = redissonClient.getBucket("signCache");
        if (signCache.get() != null) {
            // 缓存存在
            HashMap<String, String> result = JSONObject.parseObject(signCache.get(), HashMap.class);
            return R.ok(result);
        } else {
            AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest()
                    //有晓时间为一个小时
                    .setDurationSeconds(3600L)
                    // 将<YOUR_ROLE_SESSION_NAME>设置为自定义的会话名称，例如 my-website-server。
                    .setRoleSessionName("ramosstest")
                    // 将<YOUR_ROLE_ARN>替换为拥有上传文件到指定OSS Bucket权限的RAM角色的ARN，可以在 RAM 角色详情中获得角色 ARN。
                    .setRoleArn("acs:ram::1849398496984852:role/ramosstest");
            RuntimeOptions runtime = new RuntimeOptions();
            try {
                AssumeRoleResponse response = stsClient.assumeRoleWithOptions(assumeRoleRequest, runtime);
                AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials credentials = response.body.credentials;

                HashMap map = new HashMap();
                map.put("accessKeyId", stsClient.getAccessKeyId());
                map.put("accessKeySecret", stsClient.getAccessKeySecret());
                map.put("expiration", System.currentTimeMillis() + 3000 * 1000);
                map.put("securityToken", credentials.getSecurityToken());
                map.put("host", "http://shoeswasher.oss-cn-heyuan.aliyuncs.com");

                map.put("dir", "/public/img/");
                // 1天过期
                signCache.set(JSONObject.toJSONString(map), 3000, TimeUnit.SECONDS);
                return R.ok(map);
            } catch (TeaException error) {
                log.error(error);
                return R.fail(error.getMessage());
            } catch (Exception error) {
                log.error(error);
                return R.fail(error.getMessage());
            }
        }
    }

    public static byte[] hmacsha256(byte[] key, String data) {
        try {
            // 初始化HMAC密钥规格，指定算法为HMAC-SHA256并使用提供的密钥。
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacSHA256");
            // 获取Mac实例，并通过getInstance方法指定使用HMAC-SHA256算法。
            Mac mac = Mac.getInstance("HmacSHA256");
            // 使用密钥初始化Mac对象。
            mac.init(secretKeySpec);
            // 执行HMAC计算，通过doFinal方法接收需要计算的数据并返回计算结果的数组。
            byte[] hmacBytes = mac.doFinal(data.getBytes());
            return hmacBytes;
        } catch (Exception e) {
            throw new RuntimeException("Failed to calculate HMAC-SHA256", e);
        }
    }

}
